using COC.Debug;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using COC.CEvent;
using COC.Character;

namespace COC.Service
{
		[Serializable]
    public abstract class IService : ContextWrapper, System.IComparable
		{
				public System.Guid id = System.Guid.NewGuid ();

				public  string serviceName{ get { return ToString (); } }

				private Queue<CEventHandler> queue = new Queue<CEventHandler> ();
				protected CNotification notification;

				public int CompareTo (object obj)
				{
						IService another = (IService)obj;
						return this.serviceName.CompareTo (another.serviceName);
				}

				public override string ToString ()
				{
						return string.Format (this.GetType ().Name);
				}

				public override bool Equals (object obj)
				{
						return this.serviceName.Equals (((IService)obj).serviceName);
				}

				public override int GetHashCode ()
				{
						return base.GetHashCode ();
				}

				public void SubscribeEvent (CEventHandler handler)
				{
						Enqueue (handler);
				}

				private void Enqueue (CEventHandler handler)
				{
						queue.Enqueue (handler);
				}

				private void Dequeue (CEventHandler handler)
				{
						queue.Dequeue ();
				}

				private IEnumerator DoExecute ()
				{
						while (true) {
                           // DebugTool.Log("previous queue.Count:" + queue.Count);
								if (queue.Count > 0) {
										CEventHandler e = queue.Peek ();
										//Queue<CEventHandler>.Enumerator iterator = queue.GetEnumerator ();
										//while (iterator.MoveNext()) {
										//CEventHandler e = iterator.Current;
										lock (e) {
												Execute (e);
												if (notification != null) {
														BaseBehaviour _source = (BaseBehaviour)e.source;
                                                        DebugTool.Log("Event Action = " + e.action + ".");
                                                        DebugTool.Log("action source:" + _source);
														_source.SendBroadcast (notification);

												}
												Dequeue (e);
                                                DebugTool.Log("consequent queue.Count:" + queue.Count);
										}
								}
								yield return new WaitForFixedUpdate ();
						}
				}
				
		        
				/// <summary>
				/// Execute the specified cEvent.support for subclass and subclass to be overrided this function
				/// </summary>
				/// <param name="cEvent">C event.</param>
				protected virtual void Execute (CEventHandler cEvent)
				{
				}
		        
				void Start ()
				{
                    wireComponent();
						StartCoroutine ("DoExecute");
				}

                public virtual void wireComponent()
				{

				}

				public void Stop ()
				{
						queue.Clear ();
						StopCoroutine ("DoExecute");
						Destroy (this);
				}


		}


}